C++中local static对象与non-local static对象的概念与区别

C++中的static对象是指存储区不属于stack和heap、”寿命”从被构造出来直至程序结束为止的对象。这些对象包括全局对象,定义于namespace作用域的对象,在class、function以及file作用域中被声明为static的对象。其中,函数内的static对象称为local static 对象,而其它static对象称为non-local static对象。

这两者在何时被初始化(构造)这个问题上存在细微的差别:

i.对于local static对象,在其所属的函数被调用之前,该对象并不存在,即只有在第一次调用对应函数时,local static对象才被构造出来。

ii.对于non-local static对象,在main()函数开始前就已经被构造出来,并在main()函数结束后被析构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
定义ClassA和ClassB
*/
class ClassA
{
public:
ClassA(){cout<<"in Constructor of ClassA"<<endl;}
};
//
class ClassB
{
public:
ClassB(){cout<<"in Constructor of ClassB"<<endl;}
~ClassB(){cout<<"in Destructor of ClassB"<<endl;}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
包装类
*/
class WrapperClassA
{
public:
WrapperClassA(){}
ClassA& singleton()
{
static ClassA innerObjA; //local static object
return innerObjA;
}
};
1
2
3
4
5
6
7
8
9
10
/*
class with non-local static object
*/
class WrapperClassB
{
public:
WrapperClassB(){}
//static data member declaration
static ClassB innerObjB;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
static member definition
*/
ClassB WrapperClassB::innerObjB;//这局中的ClassB实例最先构造,先于main函数,并在main函数结束的时候才析构
//
int main()
{
cout<<"main() started."<<endl;
WrapperClassA objA;
objA.singleton(); //只有去掉注释执行该语句时,innerObjA才被构造出来
cout<<"main() terminated."<<endl;
return 0;
}

运行结果为:

1
2
3
4
5
in Constructor of ClassB
main() started.
in Constructor of ClassA
main() terminated.
in Destructor of ClassB

可见non-local static对象在main()函数开始前就已经被构造出来,并在main()函数结束后被析构,而local static对象只有在第一次调用对应函数时,local static对象才被构造出来。